import base64
import datetime
import random
from io import BytesIO

import requests
from django.conf import settings
# 导入工具类
# 导入HttpResponse用于返回图片流
from django.http import HttpResponse
from qiniu import Auth, put_data
from rest_framework import status
# 导入DRF的Response和APIView
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.views import APIView

from utils.jwttool import tooljwt
from utils.redis import toolredis
from utils.sendmsg import send_message
from .Ser import UserBlacklistSimpleSer, UserPreferenceSer, UserAuthHistorySer
from .Ser import UserSerializer, UserAddressSerializer
# 导入相关模型
from .models import UserPreference, UserBlacklist, User, UserAddress, UserAuthHistory, FaceRecognition
from .third_party_login_factory import DingTalkLoginFactory, LoginClient


# 短信验证码和手机号验证码登录/注册接口
class sendcode(APIView):
    # 发送短信验证码
    def get(self, request):
        phone = request.GET.get("phone")
        code = random.randint(1000, 9999)
        toolredis.setcode(phone, code)
        u = send_message(phone, code)
        if u["statusCode"] != "000000":
            return Response({"code": 201, "msg": "发送失败"})
        return Response({"code": 200, "msg": "发送成功"})

    # 手机号验证码登录/注册
    def post(self, request):
        phone = request.data.get("phone")
        code = request.data.get("code")
        verify_code = request.data.get('verify_code')
        uuid = request.data.get('uuid')
        if not phone or not code or not verify_code or not uuid:
            return Response({"code": 400, "msg": "参数不完整"})
        user = User.objects.filter(phone=phone).first()
        uidcode = toolredis.getcode(uuid)
        if uidcode != verify_code:
            return Response({"code": 201, "msg": "图形验证码错误"})
        if user:
            rcodde = toolredis.getcode(phone)
            if rcodde == code:
                token = tooljwt.getjwt({"user": user.id})
                return Response({"code": 200, "msg": "登录成功", "token": token, "user": user.id})
        else:
            User.objects.create(phone=phone)
            u = User.objects.filter(phone=phone).first()
            rcodde = toolredis.getcode(phone)
            if rcodde == code:
                token = tooljwt.getjwt({"user": u.id})
                return Response({"code": 202, "msg": "注册成功", "token": token, "user": u.id})
        return Response({"code": 201, "msg": "验证码错误"})


# 生成指定长度的随机验证码字符串
def random_code(key=4):
    str_a_z = [chr(num) for num in range(97, 122)]
    str_A_Z = [chr(num) for num in range(65, 90)]
    num_0_9 = [str(num) for num in range(0, 10)]
    return ''.join(random.sample(str_a_z + str_A_Z + num_0_9, key))


from captcha.image import ImageCaptcha


# 生成图片验证码并保存到redis
# 返回图片二进制内容
def make_verify_image(code_str, image_uuid=None):
    toolredis.setcode(image_uuid, code_str)
    image = ImageCaptcha().generate_image(code_str)
    out = BytesIO()
    image.save(out, "jpeg")
    return out.getvalue()


# 图形验证码图片接口
class ImageCodeCheckView(APIView):
    # 获取图形验证码图片
    def get(self, request):
        uuid = request.GET.get("uuid")
        code_str = random_code(4)
        image = make_verify_image(code_str, uuid)
        return HttpResponse(image, content_type="image/jpeg")


# 钉钉扫码登录跳转链接接口
class DingTalkLogin(APIView):
    def get(self, request):
        client = LoginClient(DingTalkLoginFactory())
        url = client.get_auth_url()
        return Response({"url": url})

#钉钉回调接口
class DingTalkCallback(APIView):
    def get(self, request):
        code = request.query_params.get('code')  # 修复参数获取方式
        if not code:
            return Response({"code": 400, "msg": "缺少授权码参数"})
        client = LoginClient(DingTalkLoginFactory())
        result = client.login(code)
        return Response(result)


class UserInfoView(APIView):
    """获取当前用户信息"""

    def get(self, request):
        try:
            # 从token中获取用户ID
            token = request.META.get('HTTP_AUTHORIZATION', '').replace('Bearer ', '')
            if not token:
                return Response({'code': 401, 'msg': '未提供认证token'}, status=401)

            # 这里简化处理，实际应该解析JWT token
            user_id = request.GET.get('user_id') or request.user.id if hasattr(request, 'user') else None

            if not user_id:
                # 尝试从localStorage中获取的userid
                user_id = request.GET.get('userid')

            if not user_id:
                return Response({'code': 400, 'msg': '无法获取用户ID'}, status=400)

            user = User.objects.filter(id=user_id).first()
            if not user:
                return Response({'code': 404, 'msg': '用户不存在'}, status=404)

            return Response({
                'code': 200,
                'msg': '获取成功',
                'data': {
                    'id': user.id,
                    'real_name': user.real_name,
                    'phone': user.phone,
                    'avatar': user.avatar
                }
            })

        except Exception as e:
            return Response({
                'code': 500,
                'msg': f'获取用户信息失败：{str(e)}'
            }, status=500)


# 用户登出接口
class LogoutView(APIView):
    # 用户登出
    def get(self, request):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '')
        token = ''
        if auth_header.startswith('Bearer '):
            token = auth_header[7:]
        # 解析token，获取exp字段
        payload = tooljwt.decodejwt(token)
        exp = payload.get('exp')
        import time
        now = int(time.time())
        toolredis.set_token_exp(token, exp - now)
        return Response({"code": 200, "msg": "退出成功"})


# 用户偏好设置接口
class UserPreferenceView(APIView):
    def get(self, request):
        userid = request.GET.get("userid")
        pr = UserPreference.objects.filter(user=userid).first()
        return Response(UserPreferenceSer(pr).data)

    # 添加用户偏好
    def post(self, request):
        user_id = request.data.get("user_id")
        accept_order_type = request.data.get("accept_order_type")
        preferred_area = request.data.get("preferred_area")
        if not user_id:
            return Response({"code": 400, "msg": "缺少用户ID"})
        user = User.objects.filter(id=user_id).first()
        if not user:
            return Response({"code": 404, "msg": "用户不存在"})
        if UserPreference.objects.filter(user=user).exists():
            pr = UserPreference.objects.filter(user=user).first()
            pr.accept_order_type = accept_order_type
            pr.preferred_area = preferred_area
            pr.save()
            return Response({"code": 200, "msg": "修改成功"})
        pref = UserPreference.objects.create(
            user=user,
            accept_order_type=accept_order_type,
            preferred_area=preferred_area
        )
        return Response({"code": 200, "msg": "添加成功", "id": pref.id})

    # 修改用户偏好
    def put(self, request):
        pref_id = request.data.get("id")
        accept_order_type = request.data.get("accept_order_type")
        preferred_area = request.data.get("preferred_area")
        if not pref_id:
            return Response({"code": 400, "msg": "缺少偏好ID"})
        pref = UserPreference.objects.filter(id=pref_id).first()
        if not pref:
            return Response({"code": 404, "msg": "偏好不存在"})
        if accept_order_type is not None:
            pref.accept_order_type = accept_order_type
        if preferred_area is not None:
            pref.preferred_area = preferred_area
        pref.save()
        return Response({"code": 200, "msg": "修改成功"})


# 用户黑名单接口
class UserBlacklistView(APIView):
    # 查询黑名单
    def get(self, request):
        user_id = request.GET.get("user_id")
        if not user_id:
            return Response({"code": 400, "msg": "缺少用户ID"})
        blacklists = UserBlacklist.objects.filter(user_id=user_id)
        data = UserBlacklistSimpleSer(blacklists, many=True).data
        return Response({"code": 200, "msg": "查询成功", "data": data})

    # 添加黑名单
    def post(self, request):
        user_id = request.data.get('user_id')
        target_user_id = request.data.get('target_user_id')
        black_type = request.data.get('black_type')
        reason = request.data.get('reason', '')

        if not all([user_id, target_user_id, black_type is not None]):
            return Response({'msg': '参数不完整'}, status=status.HTTP_400_BAD_REQUEST)

        blacklist = UserBlacklist.objects.create(
            user_id=user_id,
            target_user_id=target_user_id,
            black_type=black_type,
            reason=reason
        )
        return Response({'msg': '添加成功', 'id': blacklist.id}, status=status.HTTP_201_CREATED)

    # 修改黑名单
    def put(self, request):
        blacklist_id = request.data.get('id')
        black_type = request.data.get('black_type')
        reason = request.data.get('reason')

        if not blacklist_id:
            return Response({'msg': '缺少id'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            blacklist = UserBlacklist.objects.get(id=blacklist_id)
        except UserBlacklist.DoesNotExist:
            return Response({'msg': '黑名单不存在'}, status=status.HTTP_404_NOT_FOUND)

        if black_type is not None:
            blacklist.black_type = black_type
        if reason is not None:
            blacklist.reason = reason
        blacklist.save()
        return Response({'msg': '修改成功'}, status=status.HTTP_200_OK)

    def delete(self, request):
        blacklist_id = request.GET.get('id')
        if not blacklist_id:
            return Response({'msg': '缺少id'}, status=status.HTTP_400_BAD_REQUEST)
        UserBlacklist.objects.filter(id=blacklist_id).delete()
        return Response({'msg': '删除成功'}, status=status.HTTP_204_NO_CONTENT)

#用户基本信息
class UserViewSet(viewsets.ModelViewSet):
    """User表的CRUD视图集"""
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_field = "id"
    lookup_url_kwarg = "id"

    def list(self, request, *args, **kwargs):
        """重写list方法，返回用户列表"""
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            "code": 200,
            "msg": "查询成功",
            "data": serializer.data
        })

    def create(self, request, *args, **kwargs):
        """重写create方法，添加成功提示"""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return Response({
            "code": 201,
            "msg": "用户创建成功",
            "data": serializer.data
        })

    @action(methods=['post'], detail=False)
    # 定义一个名为imgurl的函数，用于处理post请求
    def imgurl(self, request):
        file = request.data.get('file')
        if not file:
            return Response({"error": "未上传文件"}, status=400)
        # 七牛云认证
        q = Auth(settings.QINIU_ACCESS_KEY, settings.QINIU_SECRET_KEY)
        key = file.name  # 七牛云保存的文件名
        token = q.upload_token(settings.QINIU_BUCKET_NAME, key, 3600)

        # 上传到七牛
        info = put_data(token, key, file.read())
        if info.status_code == 200:
            url = f"{settings.QINIU_BUCKET_DOMAIN}/{key}"
            return Response({"url": url})
        else:
            return Response({"error": "上传七牛云失败"}, status=500)

#用户地址
class UserAddressViewSet(viewsets.ModelViewSet):
    """UserAddress表的CRUD视图集"""
    queryset = UserAddress.objects.all()
    serializer_class = UserAddressSerializer
    lookup_field = "id"
    lookup_url_kwarg = "id"

    def list(self, request, *args, **kwargs):
        """重写list方法，返回地址列表"""
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            "code": 200,
            "msg": "地址查询成功",
            "data": serializer.data
        })

    def create(self, request, *args, **kwargs):
        """重写create方法，添加成功提示"""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return Response({
            "code": 201,
            "msg": "地址创建成功",
            "data": serializer.data
        })

    def update(self, request, *args, **kwargs):
        """重写update方法，添加成功提示"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        return Response({
            "code": 200,
            "msg": "地址更新成功",
            "data": serializer.data
        })

    def destroy(self, request, *args, **kwargs):
        """重写destroy方法，添加成功提示"""
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response({
            "code": 200,
            "msg": "地址删除成功"
        })


def get_access_token():
    tokenurl = "https://aip.baidubce.com/oauth/2.0/token"
    boby = {
        "grant_type": "client_credentials",
        "client_id": "QCy2DavOp0yCqHViqxFA4lYV",
        "client_secret": "IT2kcXMhl71bhGXQppQOPt9jTXEqHMDs"
    }
    access_token = requests.post(tokenurl, boby).json()["access_token"]
    return access_token


# 身份证识别
class IDCardView(APIView):
    def post(self, request):
        img_url = request.data.get('img_url')
        img_resp = requests.get(img_url)
        img_base64 = base64.b64encode(img_resp.content).decode()
        id_card_side = "front"
        request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"
        bobytoken = {
            "access_token": get_access_token(),
            "image": img_base64,
            "id_card_side": id_card_side
        }
        headers = {'content-type': 'application/x-www-form-urlencoded'}
        response = requests.post(request_url, data=bobytoken, headers=headers).json()
        if response:
            name = response["words_result"].get("姓名", {}).get("words", "")
            id_number = response["words_result"].get("公民身份号码", {}).get("words", "")
            res = {
                "name": name,
                "id_card": id_number
            }
            return Response({
                "code": 200,
                "msg": "身份证识别成功",
                "data": res
            })
        else:
            return Response({
                "code": 400,
                "msg": "身份证识别失败"
            })


# 人脸识别
class FaceView(APIView):
    def get(self,request):
        userid=request.GET.get("userid")
        userauthhistory=UserAuthHistory.objects.filter(user=User.objects.get(id=userid))
        data=UserAuthHistorySer(userauthhistory,many=True).data
        return Response(
            {
                "code": 200,
                "msg": "认证历史记录查询成功",
                "data": data
            }
        )
    def post(self, request):
        user_id = request.data.get('user_id')
        user=User.objects.filter(id=user_id).first()
        IDCARD_resp = requests.get(user.id_img_url)
        IDCARD_base64 = base64.b64encode(IDCARD_resp.content).decode()
        IDCARD_json = {
            "image": IDCARD_base64,
            "image_type": "BASE64",
            "face_type": "CERT",
            "quality_control": "LOW"
        }
        LIVE_url = request.data.get('LIVE_url')
        LIVE_resp = requests.get(LIVE_url)
        LIVE_base64 = base64.b64encode(LIVE_resp.content).decode()
        LIVE_json = {
            "image": LIVE_base64,
            "image_type": "BASE64",
            "face_type": "LIVE",
            "quality_control": "LOW"
        }
        img_json = [IDCARD_json, LIVE_json]
        token = get_access_token()
        url = "https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=" + token
        headers = {'content-type': 'application/json'}
        response = requests.post(url, json=img_json, headers=headers)
        if response:
            score = response.json().get("result", {}).get("score")
            if score is not None:
                score = round(float(score), 2)
            if score and score > 80:
                recognition_result = 1
                auth_type = 0
                auth_status = 1
                auth_time = datetime.datetime.now()
                status = 1
            else:
                recognition_result = 0
                auth_type = 0
                auth_status = 0
                auth_time = datetime.datetime.now()
                status = 0
            # 保存识别记录
            FaceRecognition.objects.create(
                user_id=user_id,
                face_image_url=LIVE_url,
                recognition_time=datetime.datetime.now(),
                recognition_result=recognition_result,
                similarity_score=score,
                created_at=datetime.datetime.now(),
                updated_at=datetime.datetime.now()
            )
            UserAuthHistory.objects.create(
                user_id=user_id,
                auth_time=auth_time,
                auth_status=auth_status,
                auth_type=auth_type,
            )
            user.status = status
            user.save()
            return Response({
                "code": 200,
                "msg": "人脸识别成功" if recognition_result else "人脸识别不通过",
                "score": score
            })
        else:
            return Response({
                "code": 400,
                "msg": "人脸识别失败"
            })